package mujmail;

/*
MujMail - Simple mail client for J2ME
Copyright (C) 2006 Nguyen Son Tung <n.sontung@gmail.com>
Copyright (C) 2008 David Hauzar <david.hauzar.mujmail@gmail.com>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

import mujmail.util.Functions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import com.sun.lwuit.Dialog;
import java.util.Vector;
import javax.microedition.lcdui.AlertType;
import lcduilwuit.*;
import com.sun.lwuit.Image;
import com.sun.lwuit.Container;
import com.sun.lwuit.events.*;
import com.sun.lwuit.events.ActionListener;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import com.sun.lwuit.list.*;
import com.sun.lwuit.Component;

/**
 * Makes possible to administer, display and search the contacts.
 */
public class AddressBook extends Form implements  ActionListener {

    /** Flag signals if we want to print debug prints */
    private static final boolean DEBUG = false;
    public //to flip recipients when Insert Recipients from sendMail
    Image selected;
    static Vector getAddresses() {
        return addresses;
    }

    public void actionPerformed(ActionEvent evt) {

       com.sun.lwuit.Command c = evt.getCommand();

          if (c == add) {
                showCntForm(null);
            } else if (c == delete) {
                delete(getSelectedIndex(), false);
            } else if (c == edit) {
                edit(getSelectedIndex());
            } else if (c == view) {
                view(getSelectedIndex());
            } else if (c == sendMail) {
                sendMail(getSelectedIndex());
            } else if (c == done) {
                pasteEmails();
            } else if (c == back) {
                back();
            } else if (c == cfBack) {
                show();
            } else if (c == cfSave) {
                saveContactForm();
            }
    }

    public static //to map contacts marked as recipients
    Hashtable getEmailHash() {
        return emailHash;
    }

    public void setEmailHash(Hashtable emailHash) {
        this.emailHash = emailHash;
    }

    /**
     * Represents one contact stored in database / vector addresses.
     */
    public static class Contact {

        String name;
        private String email;
        String notes;
        int DBIndex;

        public String getName() {
            return name;
        }

        public Contact(String name, String email, String notes) {
            this.name = name;
            this.email = email;
            this.notes = notes;
        }
        
        //#ifdef MUJMAIL_SYNC
//#         public String toString() {
//#         	return "Name: " + this.name + "\n" +
//#         	       "Email: " + this.getEmail() + "\n" +
//#         	       "Notes: " + this.notes + "\n\n";
//#         }
//#         
//#         public static Contact parseContact(String contactStr)
//#         {
//#         	String name, email, notes;
//# 	
//#         	name = contactStr.substring(contactStr.indexOf("Name: ") + 6, contactStr.indexOf('\n'));
//#         	contactStr = contactStr.substring(contactStr.indexOf("\n") + 1);
//#         	email = contactStr.substring(contactStr.indexOf("Email: ") + 7, contactStr.indexOf('\n'));
//#         	contactStr = contactStr.substring(contactStr.indexOf("\n") + 1);
//#         	notes = contactStr.substring(contactStr.indexOf("Notes: ") + 7, contactStr.indexOf('\n'));
//# 
//#         	return new Contact(name, email, notes);
//#         }
        //#endif

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }
    }

    static final byte MODE_DEFAULT = 0;
    static final byte MODE_EDIT = 1; //when editing a contact
    static final byte MODE_SENDMAIL_BROWSE = 2; //when selecting a contact to be paste in SendMail
    byte mode = MODE_DEFAULT;
    MujMail mujMail;
    Form cntForm, viewForm; //a form to create a contact; to view contact's info	
    Command /*mark,*/ done, back, delete, edit, add,/* delAll,*/ view, sendMail;
    lcduilwuit.Command cfBack, cfSave; //for contact editing form
    lcduilwuit.Command vBack; //for contact viewing form
    //Command flipRcps; //to flip recipients when Insert Recipients from sendMail
    static private Vector addresses; //a container to store contacts
    static Hashtable nameHash; //store first letters of some names for faster finding of a contact's name
    boolean  btnHidden;
    Hashtable marked; //to map contacts marked as recipients 
    static private Hashtable emailHash; //to map contacts's emails that are in the addressbook, preventing multiple entries having the same email
    /*Displayable*/Displayable nextDisplay; //a displayable that should be displayed(MailForm, SendMail) after some action (saving a contact, adding recipients)
    Image img_search; 
    com.sun.lwuit.TextField searchBox = new  com.sun.lwuit.TextField("");
    com.sun.lwuit.Label sBoxIcon=new  com.sun.lwuit.Label(Functions.getIcon("/search.png"));
    com.sun.lwuit.List addressList;
    public static void load()
    {
        Thread t = new Thread(){
            public void run()
            {
                addresses = new Vector();
                emailHash = new Hashtable();
                nameHash = new Hashtable();
                actualRun();
            }
        };
        t.start();
        t.setPriority(Thread.MAX_PRIORITY);
    }
    public AddressBook(MujMail mujMail) {
        setScrollable(false);
        this.mujMail = mujMail;
        nextDisplay = this;
        marked = new Hashtable();
        selected = Functions.getIcon("/acc_active.png");
        cfSave = new lcduilwuit.Command(Lang.get(Lang.BTN_SAVE), Command.OK, 1);
        cfBack = new  lcduilwuit.Command(Lang.get(Lang.BTN_BACK), Command.BACK, 2);
        vBack = new  lcduilwuit.Command(Lang.get(Lang.BTN_BACK), Command.BACK, 1){
            public void actionPerformed(ActionEvent evt){
                show();
            }
        };
        done = new Command(Lang.get(Lang.BTN_AD_DONE), Command.ITEM, 1);
        back = new Command(Lang.get(Lang.BTN_BACK), Command.BACK, 3);
        sendMail = new Command(Lang.get(Lang.BTN_AD_SEND_MAIL), Command.OK, 2);
        add = new Command(Lang.get(Lang.BTN_AD_ADD_NEW), Command.ITEM, 3);
        edit = new Command(Lang.get(Lang.BTN_EDIT), Command.ITEM, 4);
        delete = new Command(Lang.get(Lang.BTN_DELETE), Command.ITEM, 5);
        view = new Command(Lang.get(Lang.BTN_AD_VIEW), Command.ITEM, 6);
       searchBox.setInputModeOrder(new String[]{"abc"});
        searchBox.addDataChangeListener(new com.sun.lwuit.events.DataChangedListener(){

          public  void 	dataChanged(int type, int index)  {
                int result = search(searchBox.getText());
                if (result != -1)
                {
                    addressList.setSelectedIndex(result);
                }
            }
        
        }
        
    );
    Container cntr =new Container(Display.boxLayout_X);

    cntr.addComponent(sBoxIcon);
    cntr.addComponent(searchBox);
    addComponent(cntr);
        addCommand(back);
        addCommand(sendMail);
        addCommand(view);
        addCommand(edit);
        addCommand(add);
        addCommand(delete);
        setCommandListener(this);
        addressList = new MyList(addresses);
        addressList.setListCellRenderer(new AddressbookRenderer());
        addComponent(addressList);
        
    }

    public static void actualRun() {
        try {
            RecordStore ADRS = RecordStore.openRecordStore("AddressBook", true);

            try {
                  if (DEBUG) System.out.println("DEBUG AddressBook.run() - loading AddressBook");
                if (ADRS.getNumRecords() > 0) {
                    int id, sizeOfRecord;
                    byte[] data = new byte[50];
                    DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(data));
                    RecordEnumeration enumeration = ADRS.enumerateRecords(null, null, false);
                    getAddresses().ensureCapacity(enumeration.numRecords());
                    while (enumeration.hasNextElement()) {
                        try {

                            id = enumeration.nextRecordId();
                            sizeOfRecord = ADRS.getRecordSize(id);
                            if (sizeOfRecord > data.length) {
                                data = new byte[sizeOfRecord + 20];
                                inputStream = new DataInputStream(new ByteArrayInputStream(data));
                            }
                            ADRS.getRecord(id, data, 0);
                            inputStream.reset();

                            Contact contact = new Contact( inputStream.readUTF(), inputStream.readUTF(), inputStream.readUTF() );
                            contact.DBIndex = id;

                            getAddresses().addElement(contact);
                            getEmailHash().put(contact.getEmail(), contact);
                        } catch (Exception exp) {
                        //try another one
                        }
                    }
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    data = null;
                }
                  if (DEBUG) System.out.println("DEBUG AddressBook.run() - loading AddressBook done");
            } catch (Exception ex) {
                //mujMail.alert.setAlert(this, this, Lang.get(Lang.ALRT_AD_LOAD) + Lang.get(Lang.FAILED), MyAlert.DEFAULT, AlertType.ERROR);
                Dialog.show("",Lang.get(Lang.ALRT_AD_LOAD) + Lang.get(Lang.FAILED), Dialog.TYPE_ERROR, null,Lang.get(Lang.BTN_OK),"");
            } catch (Error er) {
              //  mujMail.alert.setAlert(this, this, Lang.get(Lang.ALRT_AD_LOAD) + Lang.get(Lang.FAILED), MyAlert.DEFAULT, AlertType.ERROR);
                Dialog.show("",Lang.get(Lang.ALRT_AD_LOAD) + Lang.get(Lang.FAILED), Dialog.TYPE_ERROR, null,Lang.get(Lang.BTN_OK),"");
            }

            ADRS.closeRecordStore();
        } catch (Exception ex) {
           // mujMail.alert.setAlert(this, this, Lang.get(Lang.ALRT_AD_LOAD) + Lang.get(Lang.FAILED), MyAlert.DEFAULT, AlertType.ERROR);
            Dialog.show("",Lang.get(Lang.ALRT_AD_LOAD) + Lang.get(Lang.FAILED), Dialog.TYPE_ERROR, null,Lang.get(Lang.BTN_OK),"");

        }
        Functions.sort(getAddresses(), Functions.SRT_ORDER_INC, Functions.SRT_CNT_NAME);
        initHash();
    }

    public int getSelectedIndex() {
        return addressList.getSelectedIndex();
    }

    public void setSelectedIndex(int i) {
       addressList.setSelectedIndex(i);
    }

 
    
    private void hideButtons() {
        if (!btnHidden) {
            removeCommand(view);
            removeCommand(sendMail);
            removeCommand(edit);
            removeCommand(delete);
            if (mode == MODE_SENDMAIL_BROWSE) {
                removeCommand(add);
            }
            btnHidden = true;
        }
    }

    private void showButtons() {
        if (btnHidden) {
            addCommand(view);
            addCommand(sendMail);
            addCommand(edit);
            addCommand(delete);
            btnHidden = false;
        }
    }

  
    public void onShow() {
        if (getAddresses().isEmpty() || mode == MODE_SENDMAIL_BROWSE) {
            hideButtons();
        } else {
            showButtons();
        }
    }
 
    //when user exits from the addressbook, defaults values
    public void back() {
        showButtons();
        if (mode == MODE_SENDMAIL_BROWSE) {
            removeCommand(done);
            addCommand(add);
            marked.clear();
        }
        if (nextDisplay != this) {
            mujMail.getDisplay().setCurrent(nextDisplay);
        } else {
            mujMail.mainMenu();
        }
        mode = MODE_DEFAULT;
        nextDisplay = this;
        cntForm = null;
        viewForm = null;
        System.out.println("Reached here");
    }


    //deletes a selected contact
    public void delete(int index, boolean sure) {
        if (0 <= index && index < getAddresses().size()) {
            Contact contact = (Contact) getAddresses().elementAt(index);
            if (!sure) {
                //mujMail.alert.setAlert(this, this, Lang.get(Lang.ALRT_SYS_DEL_CONFIRM) + contact.getEmail() + "?", MyAlert.DEL_CONFIRM, AlertType.CONFIRMATION);
                if(Dialog.show("",  Lang.get(Lang.ALRT_SYS_DEL_CONFIRM) + contact.getEmail() + "?",Dialog.TYPE_CONFIRMATION,null, Lang.get(Lang.BTN_OK), Lang.get(Lang.BTN_CANCEL)))
                {
                        //just go fiurther;
                }
                else
                    return;
            }
            try {
                delFromDB(contact);
            } catch (MyException ex) {
                mujMail.alert.setAlert(this, this, ex.getDetails(), MyAlert.DEFAULT, AlertType.ERROR);
                return;
            }
            getEmailHash().remove(contact.getEmail());
            getAddresses().removeElementAt(index);
            initHash();
            repaint();
        }
    }
    //deletes a selected contact from DB only		
    public void delFromDB(Contact contact) throws MyException {
        MyException exception = null;
        RecordStore ADRS = Functions.openRecordStore("AddressBook", true);
        try {
            ADRS.deleteRecord(contact.DBIndex);
        } catch (Exception ex) {
            exception = new MyException(MyException.DB_CANNOT_DEL_CONTACT);
        }
        Functions.closeRecordStore(ADRS);
        if (exception != null) {
            throw exception;
        }
    }

    public static void deleteAll(boolean sure) {
       /* if (!sure) {
            mujMail.alert.setAlert(this, this, Lang.get(Lang.ALRT_SYS_DEL_ALL_CONFIRM), MyAlert.DB_CLEAR_CONFIRM, AlertType.CONFIRMATION);
            return;
        }*/
        if(!sure)
        {
           if(Dialog.show("",Lang.get(Lang.ALRT_SYS_DEL_ALL_CONFIRM),Dialog.TYPE_CONFIRMATION,null,Lang.get(Lang.BTN_OK),Lang.get(Lang.BTN_CANCEL)))
           {
            //just go further
           }
           else
               return;
        }
        try {
            RecordStore.deleteRecordStore("AddressBook");
        } catch (Exception ex) {
            //mujMail.alert.setAlert(this, this, Lang.get(Lang.ALRT_AD_DELETE) + Lang.get(Lang.FAILED), MyAlert.DEFAULT, AlertType.ERROR);
            Dialog.show("",Lang.get(Lang.ALRT_AD_DELETE) + Lang.get(Lang.FAILED),Dialog.TYPE_ERROR,null,Lang.get(Lang.BTN_OK),"");
            return;
        }
        getAddresses().removeAllElements();
        getEmailHash().clear();
        nameHash.clear();
    }

    /**
     * Saves a contact from the form; returns a saved contact or null
     * (when something's gone wrong);
     */
    public void saveContactForm() {
        if (cntForm != null) {
            Contact contact = new Contact(
                    ((TextField) cntForm.get(0)).getString().trim(),
                    ((TextField) cntForm.get(1)).getString().trim(),
                    ((TextField) cntForm.get(2)).getString().trim());
            try {
                saveContact(contact);
                mujMail.getDisplay().setCurrent(nextDisplay);
            } catch (MyException ex) {
                mujMail.alert.setAlert(this, cntForm, ex.getDetailsNocode(), MyAlert.DEFAULT, AlertType.INFO);
            }
        }
    }

    /**
     * Saves to DB and containers, hashes
     * @param contact the contact to be saved
     * @throws MyException
     */
    private void saveContact(Contact contact) throws MyException {
        if (contact == null) {
            throw new MyException(MyException.DB_CANNOT_SAVE_CONTACT);
        }

        contact = saveContactToDB(contact);
        if (mode == MODE_EDIT) {
            Contact cnt = (Contact) getAddresses().elementAt(addressList.getSelectedIndex());
            getAddresses().removeElementAt(addressList.getSelectedIndex()); //remove the old one
            getEmailHash().remove(cnt.getEmail());
            mode = MODE_DEFAULT;
        }
        //refresh hashes and container
        getAddresses().addElement(contact);
        getEmailHash().put(contact.getEmail(), contact);
        Functions.sort(getAddresses(), Functions.SRT_ORDER_INC, Functions.SRT_CNT_NAME);
        initHash();
    }
    public static void directSaveContactToDatabase(Contact contact) throws MyException {
         if (contact.getEmail() == null || contact.getEmail().indexOf("@") < 1) {
            throw new MyException(MyException.VARIOUS_BAD_EMAIL);
        }
        if (getEmailHash().containsKey(contact.getEmail()) ) {
            throw new MyException(MyException.VARIOUS_AB_MULTIPLE_ENTRIES);
        }
        MyException exception = null;
        RecordStore ADRS = Functions.openRecordStore("AddressBook", true);
        try {
            ByteArrayOutputStream byteStream;
            DataOutputStream outputStream;
            byteStream = new ByteArrayOutputStream();
            outputStream = new DataOutputStream(byteStream);
            //if the name is not presented or invalid, try to guest it from the email address
            if (contact.name == null || contact.name.length() == 0) {
                contact.name = contact.getEmail().substring(0, contact.getEmail().indexOf("@"));
            }

            outputStream.writeUTF(contact.name);
            outputStream.writeUTF(contact.getEmail());
            outputStream.writeUTF(contact.notes);
            outputStream.flush();
            contact.DBIndex = ADRS.addRecord(byteStream.toByteArray(), 0, byteStream.size());
            outputStream.close();
            byteStream.close();
        } catch (Exception ex) {
            exception = new MyException(MyException.DB_CANNOT_SAVE_CONTACT);
        }
         Functions.closeRecordStore(ADRS);
        if (exception != null) {
            throw exception;
        }
        getAddresses().addElement(contact);
        getEmailHash().put(contact.getEmail(), contact);
        Functions.sort(getAddresses(), Functions.SRT_ORDER_INC, Functions.SRT_CNT_NAME);
        initHash();
    }
    //saves a given contact do DB.
    public Contact saveContactToDB(Contact contact) throws MyException {
        //for the sake of simplicity we just try to determine if there's any charakter before the @
        if (contact.getEmail() == null || contact.getEmail().indexOf("@") < 1) {
            throw new MyException(MyException.VARIOUS_BAD_EMAIL);
        }
        if ((getEmailHash().containsKey(contact.getEmail())) && mode != MODE_EDIT) {
            throw new MyException(MyException.VARIOUS_AB_MULTIPLE_ENTRIES);
        }
        MyException exception = null;
        RecordStore ADRS = Functions.openRecordStore("AddressBook", true);
        try {
            ByteArrayOutputStream byteStream;
            DataOutputStream outputStream;
            byteStream = new ByteArrayOutputStream();
            outputStream = new DataOutputStream(byteStream);
            if (mode == MODE_EDIT) {
                contact.DBIndex = ((Contact) getAddresses().elementAt(addressList.getSelectedIndex())).DBIndex;
            }
            //if the name is not presented or invalid, try to guest it from the email address
            if (contact.name == null || contact.name.length() == 0) {
                contact.name = contact.getEmail().substring(0, contact.getEmail().indexOf("@"));
            }

            outputStream.writeUTF(contact.name);
            outputStream.writeUTF(contact.getEmail());
            outputStream.writeUTF(contact.notes);
            outputStream.flush();
            /*buggy setRecord() method not only on the WTK emulator
            if (mode != MODE_EDIT) 
            contact.DBIndex = ADRS.addRecord( byteStream.toByteArray(), 0, byteStream.size() );			
            else 
            ADRS.setRecord(contact.DBIndex, byteStream.toByteArray(), 0, byteStream.size() );
             */
            int oldIndex = contact.DBIndex;
            contact.DBIndex = ADRS.addRecord(byteStream.toByteArray(), 0, byteStream.size());
            if (mode == MODE_EDIT) {
                ADRS.deleteRecord(oldIndex);
            }

            outputStream.close();
            byteStream.close();
        } catch (Exception ex) {
            exception = new MyException(MyException.DB_CANNOT_SAVE_CONTACT);
        }

        Functions.closeRecordStore(ADRS);
        if (exception != null) {
            throw exception;
        }
        return contact;
    }

    //edits a selected contact
    public void edit(int index) {
        if (0 <= index && index < getAddresses().size()) {
            Contact contact = (Contact) getAddresses().elementAt(index);
            mode = MODE_EDIT;
            cntForm = createCntForm();
            ((TextField) cntForm.get(0)).setString(contact.name);
            ((TextField) cntForm.get(1)).setString(contact.getEmail());
            ((TextField) cntForm.get(2)).setString(contact.notes);
            mujMail.getDisplay().setCurrent(cntForm);
        }
    }

    //creates a Contact form so we can add or edit a contact
    private Form createCntForm() {
        TextField name, email, notes;
        cntForm = new Form(Lang.get(Lang.AD_CONTACT_INFO));
        name = new TextField(Lang.get(Lang.AD_NAME), "", 50, TextField.ANY);
        if ( Properties.textFieldMailIncorrect ) {
            email = new TextField(Lang.get(Lang.AD_EMAIL), "@", 512, TextField.ANY);
        } else { 
            email = new TextField(Lang.get(Lang.AD_EMAIL), "@", 512, TextField.EMAILADDR);
         }
        notes = new TextField(Lang.get(Lang.AD_NOTES), "", 1000, TextField.ANY);

        cntForm.append(name);
        cntForm.append(email);
        cntForm.append(notes);
        cntForm.addCommand(cfBack);
        cntForm.addCommand(cfSave);
        cntForm.setCommandListener(this);
        return cntForm;
    }

    //if its called from mailForm and a mail address is given, then the string MailFormAddress is the email address
    //so after saving the email address, we can return display focus to MailForm; otherwise string MailFormAddress is null
    public void showCntForm(String MailFormAddress) {
        cntForm = createCntForm();
        nextDisplay = mujMail.getDisplay().getCurrent();//getCurrent();
        mujMail.getDisplay().setCurrent(cntForm);
        if (MailFormAddress != null) { //was is call by MailForm?
            ((TextField) cntForm.get(0)).setString(MailFormAddress);
        }
    }

    //creates a Hashtable for faster searching using the first letter of each name as index 
    //something like the indexes in the real life phonebook
    private static  void initHash() {
        nameHash.clear();
        if (getAddresses().isEmpty()) {
            return;
        }

        char firstLetter = ((Contact) getAddresses().firstElement()).name.charAt(0);
        firstLetter = Character.toLowerCase(firstLetter);
        nameHash.put(new Character(firstLetter), new Integer(0));
        int size = getAddresses().size();
        char cntNameFL; //first letter of a contact's name

        for (int i = 1; i < size; i++) {
            cntNameFL = ((Contact) getAddresses().elementAt(i)).name.charAt(0);
            cntNameFL = Character.toLowerCase(cntNameFL);

            if (firstLetter != cntNameFL) {
                firstLetter = cntNameFL;
                nameHash.put(new Character(firstLetter), new Integer(i));
            }
        }
    }

    //returns index of the most matched contact
    public int search(String name) {
        if (name == null || name.length() == 0) {
            return -1;
        }
        name.toLowerCase();
        Integer i = (Integer) nameHash.get(new Character(name.charAt(0))); //get the closest index
        if (i == null) //if its first letter was never indexed
        {
            return -1;
        }

        int size = getAddresses().size(), index = i.intValue();
        String contactName = null;
        //lets find its correct position (index)
        while (index < size) {
            contactName = ((Contact) getAddresses().elementAt(index)).name.toLowerCase();
            if (contactName.charAt(0) != name.charAt(0)) //has different first letter
            {
                return -1;
            } //not found
            if (contactName.compareTo(name) < 0) //name should be after the contactName
            {
                index++;
            } else {
                break;
            } //found or name lies before contactName
        }
        if (contactName.startsWith(name)) //now check if it really matches
        {
            return index;
        } else {
            return -1;
        }
    }
    
    //views a contact info
    public void view(int index) {
        if (0 <= index && index < getAddresses().size()) {
            viewForm = new Form(Lang.get(Lang.AD_CONTACT_INFO));
            Contact contact = (Contact) getAddresses().elementAt(index);
            viewForm.append(new StringItem(Lang.get(Lang.AD_NAME), contact.name));
            viewForm.append(new StringItem(Lang.get(Lang.AD_EMAIL),contact.getEmail()));
            viewForm.append(new StringItem(Lang.get(Lang.AD_NOTES), contact.notes));
            viewForm.addCommand(vBack);
            viewForm.setCommandListener(mujMail);

            mujMail.getDisplay().setCurrent(viewForm);
        }
    }
    //sends a selected contact a mail
    public void sendMail(int index) {
        if (0 <= index && index < getAddresses().size()) {
            Contact contact = (Contact) getAddresses().elementAt(addressList.getSelectedIndex());
            SendMail sendmail = new SendMail(mujMail);
            sendmail.to.setString("\"" + contact.name + "\" <" + contact.getEmail() + ">");

            mujMail.getDisplay().setCurrent(sendmail);
        }
    }

    //is called when a Form wants to add emails from the addressbook
    public void addEmails(Form form) {
        nextDisplay = form;
        mode = MODE_SENDMAIL_BROWSE;
        addCommand(done);
        mujMail.getDisplay().setCurrent(this);
    }

    //is called when the user confirms adding emails and wants to paste all those emails addresses to a form;
    public void pasteEmails() {
        StringBuffer emailBf = new StringBuffer();
        Contact contact;
        //probably old - and doesn't work
        //Object otfield = mujMail.sendMail.getSelectedItem() == null? mujMail.sendMail.to: mujMail.sendMail.getSelectedItem();
        //TextField tfield=null;
        /*if(otfield instanceof TextField)
        {
            tfield = (TextField)otfield;
        }
        else if (otfield instanceof com.sun.lwuit.TextArea)
        {
              tfield.insert(emailBf.toString(), tfield.getCaretPosition());
              back();
              return;
        }
        //newer
        switch(recipientChoice) {
            case 0:
                tfield = mujMail.sendMail.to;
                break;
            case 1:
                tfield = mujMail.sendMail.cc;
                break;
            case 2:
                tfield = mujMail.sendMail.bcc;
                break;
        }*/
       // Object otfield = mujMail.sendMail.getFocused();
        Object otfield = ((SendMail)nextDisplay).getFocused();
        if (otfield instanceof com.sun.lwuit.TextArea)
        {
            com.sun.lwuit.TextArea component = ((com.sun.lwuit.TextArea)otfield);//.getText();
            for (Enumeration e = marked.elements(); e.hasMoreElements(); ) {
                contact = (Contact) e.nextElement();
                if (component.getText().indexOf(contact.getEmail()) == -1) {
                    emailBf.append("\"" + contact.name + "\" <" + contact.getEmail() + ">, ");
                }
            }
           if (component != ((SendMail)nextDisplay).body) {
                component.setText(emailBf.toString() + component.getText());
            } else {
                component.setText(component.getText() + emailBf.toString());
                //component.insert(emailBf.toString(), component.getCaretPosition());
            }

        }
        /*for (Enumeration e = marked.elements(); e.hasMoreElements(); ) {
            contact = (Contact) e.nextElement();
            if (tfield.getString().indexOf(contact.getEmail()) == -1) {
                emailBf.append("\"" + contact.name + "\" <" + contact.getEmail() + ">, ");
            }
        }*/
        
        // 
        /*if ((tfield == mujMail.sendMail.cc || tfield == mujMail.sendMail.bcc) && emailBf.length() > 0 )
            mujMail.sendMail.addBc();*/

        back();
    }

   
        
    //is called when the user un/mark a contact in the addressbook
    public void markEmail(int index) {
        if (index < getAddresses().size()) {
            Contact contact = (Contact) getAddresses().elementAt(index);
            if (!marked.containsKey(contact.email)) {
                marked.put(contact.getEmail(), contact);
            } else {
                marked.remove(contact.getEmail());
            }
            repaint();
        }
    }

    public static  String getContactName(String email) {
        if (email == null) {
            return null;
        }
        if (!emailHash.containsKey(email)) {
            return null;
        }
        return ((Contact) getEmailHash().get(email)).name;
    }
     class MyList extends com.sun.lwuit.List {
        long tickTime = System.currentTimeMillis();
        MyList(Vector items) {
            super(items);
        }
        MyList() {
            super();
        }
        public void keyReleased(int key) {
            int gameAction = com.sun.lwuit.Display.getInstance().getGameAction(key);
            if (gameAction == com.sun.lwuit.Display.GAME_FIRE) {
                markEmail(getSelectedIndex());
            } else {
                super.keyReleased(key);
            }
        }

        /* public boolean animate() {
        boolean val = super.animate();
        if (hasFocus()) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - tickTime > 100) {
        if (lastSelection == getSelectedIndex()) {
        //      rndr.incrementPosition();
        } else {
        lastSelection = getSelectedIndex();
        //     rndr.resetPosition();
        }
        tickTime = System.currentTimeMillis();
        return true;
        }
        }
        return val;
        }*/
    }

    class AddressbookRenderer extends DefaultListCellRenderer {
        public AddressbookRenderer() {
            super(false);
        }
        public Component getListCellRendererComponent(com.sun.lwuit.List list, java.lang.Object value, int index, boolean isSelected) {
            Contact contact = (Contact) value;
            setText(contact.getName());
            if (marked.containsKey(contact.getEmail())) //if the contact was marked
            {
                setIcon(selected);
            } else {
                setIcon(null);
            }
            getStyle().setBgTransparency(0);
            return this;
        }
    }

}
